# 导入 collections 模块，用于创建具名元组（namedtuple）
import collections

# 定义一个具名元组 Card，表示一张扑克牌，包含 rank（点数）和 suit（花色）两个字段
Card = collections.namedtuple('Card', ['rank', 'suit'])

# 定义一个 FrenchDeck 类，表示一副标准的法国扑克牌（52张）
class FrenchDeck:
    # 定义所有可能的点数：2-10, J, Q, K, A
    ranks = [str(n) for n in range(2, 11)] + list('JQKA')
    
    # 定义所有花色：黑桃（spades）、方块（diamonds）、梅花（clubs）、红心（hearts）
    suits = 'spades diamonds clubs hearts'.split()
    
    # 初始化方法，创建一副完整的扑克牌
    def __init__(self):
        # 使用列表推导式生成所有牌的组合（先遍历花色，再遍历点数）
        self._cards = [Card(rank, suit) for suit in self.suits
                       for rank in self.ranks]
    
    # 实现 __len__ 方法，使得可以使用 len(deck) 获取牌的总数
    def __len__(self):
        return len(self._cards)
    
    # 实现 __getitem__ 方法，使得可以使用 deck[index] 或切片访问牌
    def __getitem__(self, position):
        return self._cards[position]

# 创建一副扑克牌
deck = FrenchDeck()

# 打印 deck[12::13] 的结果（每隔13张取一张，从第12张开始）
# 由于牌是按花色和点数顺序排列的，所以会取出所有花色的 A（Ace）
print(deck[12::13])  # 输出：[Card(rank='A', suit='spades'), ..., Card(rank='A', suit='hearts')]

# 定义花色的权重（用于排序），spades（黑桃）最高，clubs（梅花）最低
suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0)

# 定义一个函数 spades_high，用于计算一张牌的排序权重
def spades_high(card):
    # 获取该牌的点数在 ranks 列表中的索引（2的索引是0，A的索引是12）
    rank_value = FrenchDeck.ranks.index(card.rank)
    
    # 计算总权重：点数权重 * 4（花色数量） + 花色权重
    # 这样点数高的牌总是排在前面，同点数时按花色排序
    return rank_value * len(suit_values) + suit_values[card.suit]

# 使用 sorted 对整副牌进行排序，排序规则是 spades_high 函数
# 这样牌会按点数从小到大（2最小，A最大），同点数时按花色（黑桃 > 红心 > 方块 > 梅花）排序
for card in sorted(deck, key=spades_high):
    print(card)  # 输出排序后的牌（2♣, 2♦, 2♥, 2♠, ..., A♣, A♦, A♥, A♠）

'''
关键点解释：
​**deck[12::13]**​：
由于牌是按 suits 和 ranks 的顺序排列的（先遍历花色，再遍历点数），所以索引 12 是 spades A，25 是 diamonds A，38 是 clubs A，51 是 hearts A。
[12::13] 表示从第 12 张开始，每隔 13 张取一张，因此会取出所有花色的 A。
​**spades_high 排序逻辑**​：
rank_value 是点数在 ranks 列表中的索引（2→0, 3→1, ..., A→12）。
suit_values 是花色的权重（黑桃最高，梅花最低）。
排序权重计算公式：rank_value * 4 + suit_values[card.suit]，确保点数优先，同点数时按花色排序。
​排序后的输出顺序​：
从小到大：2♣, 2♦, 2♥, 2♠, 3♣, ..., A♣, A♦, A♥, A♠。
'''